package com.starleague.battletech.game.jpa.appengine;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;

import com.starleague.battletech.game.BattletechPhase;
import com.starleague.battletech.game.IMutableBattletechGame;
import com.starleague.battletech.game.IMutableBattletechTeam;
import com.starleague.battletech.game.dto.IBattletechGameDto;
import com.starleague.battletech.hexagonal.jpa.appengine.BattletechHexGridGae;
import com.starleague.battletech.unit.IMutableBattletechUnit;
import com.starleague.battletech.unit.jpa.appengine.BattletechUnitGae;
import com.starleague.battletech.unit.mech.jpa.appengine.MechGae;
import com.starleague.game.jpa.appengine.AbstractGameGae;

@Entity(name = "BATTLETECH_GAME")
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class BattletechGameGae
        extends AbstractGameGae
        implements IMutableBattletechGame, IBattletechGameDto
{
    @OneToMany(mappedBy = "game", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<BattletechTeamGae> teams;

    @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
    private BattletechHexGridGae hexGrid;

    @OneToMany(mappedBy = "game", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<MechGae> mechs;

    @Basic(optional = false)
    @Column(nullable = false)
    private int turn;

    @Basic(optional = false)
    @Column(nullable = false)
    private BattletechPhase phase;

    @Basic(fetch = FetchType.LAZY, optional = true)
    @Column(nullable = true)
    private BattletechTeamGae currentTeam;

    @Basic(fetch = FetchType.LAZY, optional = true)
    @Column(nullable = true)
    private MechGae currentMech;

    BattletechGameGae(String name)
    {
        super(name);
        this.teams = new ArrayList<>();
        this.mechs = new ArrayList<>();
        this.phase = BattletechPhase.NONE;
    }

    protected BattletechGameGae()
    {
        //
    }

    @Override
    public BattletechHexGridGae getHexGrid()
    {
        return this.hexGrid;
    }

    public void setHexGrid(BattletechHexGridGae hexGrid)
    {
        this.hexGrid = hexGrid;
    }

    @Override
    public List<BattletechTeamGae> getTeams()
    {
        return this.teams;
    }

    @Override
    public List<? extends BattletechUnitGae> getUnits()
    {
        return this.mechs;
    }

    public List<MechGae> getMechs()
    {
        return this.mechs;
    }

    @Override
    public int getTurn()
    {
        return this.turn;
    }

    @Override
    public void setTurn(int turn)
    {
        this.turn = turn;
    }

    @Override
    public BattletechPhase getPhase()
    {
        return this.phase;
    }

    @Override
    public void setPhase(BattletechPhase phase)
    {
        this.phase = phase;
    }

    @Override
    public BattletechTeamGae getCurrentTeam()
    {
        return this.currentTeam;
    }

    @Override
    public void setCurrentTeam(IMutableBattletechTeam currentTeam)
    {
        this.currentTeam = (BattletechTeamGae) currentTeam;
    }

    @Override
    public BattletechUnitGae getCurrentUnit()
    {
        return this.currentMech;
    }

    @Override
    public void setCurrentUnit(IMutableBattletechUnit currentUnit)
    {
        this.currentMech = (MechGae) currentUnit;
    }

    @Override
    public Map<String, Object> infoProperties()
    {
        Map<String, Object> infoPropertyMap = super.infoProperties();
        infoPropertyMap.put("turn", this.turn);
        infoPropertyMap.put("phase", this.phase);
        infoPropertyMap.put("hexGrid", this.hexGrid);
        infoPropertyMap.put("teams", this.teams);
        infoPropertyMap.put("currentTeam", this.currentTeam);
        infoPropertyMap.put("mechs", this.mechs);
        infoPropertyMap.put("currentMech", this.currentMech);
        return infoPropertyMap;
    }
}
